#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "debugger.h"

// 测试函数
void test_function_1(int x) {
    printf("测试函数1: %d\n", x);
}

int test_function_2(int a, int b) {
    printf("测试函数2: %d + %d\n", a, b);
    return a + b;
}

void test_function_3() {
    printf("测试函数3\n");
    test_function_1(42);
    test_function_2(10, 20);
}

// 单元测试函数
void test_dwarf_loading() {
    printf("=== 测试DWARF信息加载 ===\n");
    
    debugger_t *dbg = debugger_create();
    assert(dbg != NULL);
    
    // 测试加载当前程序的DWARF信息
    int result = debugger_load_dwarf_info(dbg, "./test_dwarf");
    if (result == 0) {
        printf("✓ DWARF信息加载成功\n");
        
        // 测试地址到行号映射
        char filename[256];
        unsigned int line;
        uintptr_t main_addr = debugger_resolve_symbol(dbg, "main");
        
        if (main_addr != 0) {
            if (debugger_find_line_by_address(dbg, main_addr, filename, sizeof(filename), &line) == 0) {
                printf("✓ 地址到行号映射成功: 0x%lx -> %s:%u\n", main_addr, filename, line);
            } else {
                printf("✗ 地址到行号映射失败\n");
            }
        }
        
        // 测试行号到地址映射
        uintptr_t addr = debugger_find_address_by_line(dbg, "test_dwarf.c", __LINE__ + 5);
        if (addr != 0) {
            printf("✓ 行号到地址映射成功: test_dwarf.c:%d -> 0x%lx\n", __LINE__ + 5, addr);
        } else {
            printf("✗ 行号到地址映射失败\n");
        }
    } else {
        printf("✗ DWARF信息加载失败（可能是编译选项问题）\n");
    }
    
    debugger_destroy(dbg);
    printf("=== DWARF测试完成 ===\n\n");
}

void test_stack_trace() {
    printf("=== 测试栈帧回溯 ===\n");
    
    debugger_t *dbg = debugger_create();
    assert(dbg != NULL);
    
    // 创建一个简单的测试程序
    char *args[] = {"./test_stack", NULL};
    if (debugger_launch(dbg, "./test_stack", args) == 0) {
        printf("✓ 测试程序启动成功\n");
        
        // 在function_c设置断点
        uintptr_t func_c_addr = debugger_resolve_symbol(dbg, "function_c");
        if (func_c_addr != 0) {
            if (debugger_set_breakpoint(dbg, func_c_addr) == 0) {
                printf("✓ 断点设置成功\n");
                
                // 继续执行到断点
                if (debugger_continue(dbg) == 0) {
                    printf("✓ 程序执行到断点\n");
                    
                    // 测试栈回溯
                    printf("=== 栈回溯测试 ===\n");
                    debugger_print_backtrace(dbg);
                    printf("=== 栈回溯测试完成 ===\n");
                    
                    printf("✓ 栈帧回溯功能正常\n");
                } else {
                    printf("✗ 程序执行失败\n");
                }
            } else {
                printf("✗ 断点设置失败\n");
            }
        } else {
            printf("✗ 符号解析失败\n");
        }
        
        debugger_detach(dbg);
    } else {
        printf("✗ 测试程序启动失败\n");
    }
    
    debugger_destroy(dbg);
    printf("=== 栈帧测试完成 ===\n\n");
}

void test_symbol_resolution() {
    printf("=== 测试符号解析 ===\n");
    
    debugger_t *dbg = debugger_create();
    assert(dbg != NULL);
    
    // 测试符号解析
    uintptr_t main_addr = debugger_resolve_symbol(dbg, "main");
    uintptr_t func1_addr = debugger_resolve_symbol(dbg, "test_function_1");
    uintptr_t func2_addr = debugger_resolve_symbol(dbg, "test_function_2");
    
    if (main_addr != 0) printf("✓ main函数地址解析: 0x%lx\n", main_addr);
    else printf("✗ main函数地址解析失败\n");
    
    if (func1_addr != 0) printf("✓ test_function_1地址解析: 0x%lx\n", func1_addr);
    else printf("✗ test_function_1地址解析失败\n");
    
    if (func2_addr != 0) printf("✓ test_function_2地址解析: 0x%lx\n", func2_addr);
    else printf("✗ test_function_2地址解析失败\n");
    
    debugger_destroy(dbg);
    printf("=== 符号解析测试完成 ===\n\n");
}

int main() {
    printf("开始DWARF和栈帧功能单元测试\n\n");
    
    // 编译测试程序
    printf("编译测试程序...\n");
    system("gcc -g -o test_dwarf test_dwarf.c debugger.c symbols.c dwarf.c");
    system("gcc -g -o test_stack test_stack.c");
    
    // 运行测试
    test_dwarf_loading();
    test_symbol_resolution();
    test_stack_trace();
    
    printf("所有测试完成！\n");
    
    // 清理
    remove("test_dwarf");
    
    return 0;
}